package by.zmy.aop;

import java.lang.reflect.Method;

public abstract class PointcutAspect implements Aspect {
    private final Pointcut pointcut;

    protected PointcutAspect(Pointcut pointcut) {
        this.pointcut = pointcut;
    }

    @Override
    public void before(Object target, Method method, Object[] args) {
        if (pointcut.matches(target.getClass(), method)) {
            doBefore(target, method, args);
        }
    }

    @Override
    public void after(Object target, Method method, Object[] args, Object result) {
        if (pointcut.matches(target.getClass(), method)) {
            doAfter(target, method, args, result);
        }
    }

    @Override
    public Object around(Object target, Method method, Object[] args, MethodInvocation invocation) throws Throwable {
        if (!pointcut.matches(target.getClass(), method)) {
            return invocation.proceed();
        }
        return doAround(target, method, args, invocation);
    }

    // 确保默认实现调用proceed()
    protected Object doAround(Object target, Method method, Object[] args, MethodInvocation invocation) throws Throwable {
        return invocation.proceed();
    }

    protected void doBefore(Object target, Method method, Object[] args) {}
    protected void doAfter(Object target, Method method, Object[] args, Object result) {}
}
